using System.Web.Mvc;
using System.Web.UI.WebControls;
using ExtendedMvc.Common.Diagnostics;
using ExtendedMvc.Html;

namespace ExtendedMvc.Elements {
	public class Image : ImageBase<Image> {
		public Image(string source, string id = null) : base(source, id) { }
	}

	public abstract class ImageBase<T> : VisibleElement<T> where T : ImageBase<T> {
		private string _source;
		private Unit? _width;
		private Unit? _height;

		protected string source { get { return _source; } }

		protected ImageBase(string source, string id = null)
			: base(HtmlTag.Image, id) {
			_source = source;
		}

		public virtual T Source(string value) {
			Check.Argument.IsNotNullOrEmpty(value, "Image.Source");
			_source = value;
			return (T)this;
		}

		#region Size
		public virtual T Size(int width, int height) {
			Check.Argument.IsNotNegative(width, "width");
			Check.Argument.IsNotNegative(height, "height");
			_width = new Unit(width);
			_height = new Unit(height);
			return (T)this;
		}

		public virtual T Size(string width, string height) {
			Check.Argument.IsNotNullOrEmpty(width, "width");
			Check.Argument.IsNotNullOrEmpty(height, "height");
			_width = new Unit(width);
			_height = new Unit(height);
			return (T)this;
		}

		public virtual T Size(Unit width, Unit height) {
			Check.Argument.IsNotNull(width, "width");
			Check.Argument.IsNotNull(height, "height");
			_width = width;
			_height = height;
			return (T)this;
		}
		#endregion

		#region Width
		public virtual T Width(int width) {
			Check.Argument.IsNotNegative(width, "width");
			_width = new Unit(width);
			return (T)this;
		}

		public virtual T Width(string width) {
			Check.Argument.IsNotNullOrEmpty(width, "width");
			_width = new Unit(width);
			return (T)this;
		}

		public virtual T Width(Unit width) {
			Check.Argument.IsNotNull(width, "width");
			_width = width;
			return (T)this;
		}
		#endregion

		#region Height
		public virtual T Height(int height) {
			Check.Argument.IsNotNegative(height, "height");
			_height = new Unit(height);
			return (T)this;
		}

		public virtual T Height(string height) {
			Check.Argument.IsNotNullOrEmpty(height, "height");
			_height = new Unit(height);
			return (T)this;
		}

		public virtual T Height(Unit height) {
			Check.Argument.IsNotNull(height, "height");
			_height = height;
			return (T)this;
		}
		#endregion

		protected override TagRenderMode TagRenderMode { get { return TagRenderMode.SelfClosing; } }

		protected override void Prepare() {
			SetAttribute(HtmlAttribute.Src, _source);
			if (_width != null) SetAttribute(HtmlAttribute.Width, _width.ToString());
			if (_height != null) SetAttribute(HtmlAttribute.Height, _height.ToString());
			base.Prepare();
		}
	}
}